use crate::dto::ipv4::Ipv4;
use crate::dto::ipv6::Ipv6;
use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
use std::fmt::{Display, Formatter};

#[derive(
    Serialize_repr,
    Deserialize_repr,
    num_enum::TryFromPrimitive,
    num_enum::IntoPrimitive,
    Debug,
    Clone,
    Eq,
    PartialEq,
)]
#[repr(u32)]
pub enum EndpointType {
    Srv6OverWireguard = 1,
}

impl EndpointType {
    pub fn as_u32(&self) -> u32 {
        self.clone().into()
    }
}

impl Display for EndpointType {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let v: u32 = self.as_u32();
        u32::fmt(&v, f)
    }
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Endpoint {
    pub node_id: String,
    pub endpoint_type: EndpointType,
    pub name: String,
    pub description: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub ipv4: Option<Ipv4>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub ipv6: Option<Ipv6>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct EndpointItem {
    pub endpoint_id: String,
    #[serde(flatten)]
    pub inner: Endpoint,
}